"""
REACT（Reasoning + Acting）是一种先进的AI代理框架，它让语言模型能够通过思考-行动的循环来解决复杂问题：
REACT的核心思想：
Reasoning（推理）：模型先思考问题，分析需要什么信息和步骤
Acting（行动）：模型选择并执行合适的工具来获取信息
循环迭代：基于工具返回的结果，继续思考下一步，直到解决问题\

 这个示例演示如何使用LangGraph创建REACT（Reasoning + Acting）代理
"""

import os
from dotenv import load_dotenv
from langchain_openai import ChatOpenAI

# 加载环境变量，从.env文件中读取API密钥等配置
load_dotenv()

# 初始化ChatOpenAI模型实例
# 配置参数说明：
# - api_key: 从环境变量获取API密钥
# - openai_api_base: API基础地址
# - model: 指定使用的模型为"Qwen/Qwen3-32B"
# - streaming: 启用流式输出
# - temperature: 控制生成文本的随机性，0.7表示中等创造性
llm = ChatOpenAI(
    api_key=os.getenv("MODELSCOPE_API_KEY"),
    openai_api_base=os.getenv("MODELSCOPE_API_BASE"),
    model="Qwen/Qwen3-32B",
    streaming=True,
    temperature=0.7
)

# 对于本教程，我们将使用一个自定义工具，该工具返回两个城市（纽约和旧金山）的预定义天气值
from typing import Literal
from langchain_core.tools import tool


# 使用@tool装饰器定义一个工具函数get_weather
# 这个工具模拟获取天气信息的功能
@tool
def get_weather(city: Literal["nyc", "sf"]):
    """使用此工具获取天气信息。"""
    # 根据输入的城市返回预定义的天气信息
    if city == "nyc":
        return "纽约可能是多云天气"
    elif city == "sf":
        return "旧金山总是阳光明媚"
    else:
        # 如果输入了不支持的城市，抛出错误
        raise AssertionError("未知城市")


# 将工具放入一个列表中，供代理使用
tools = [get_weather]

# 导入create_react_agent函数，用于创建REACT代理
# REACT代理结合推理(Reasoning)和行动(Acting)来解决问题
from langgraph.prebuilt import create_react_agent

# 使用指定的语言模型和工具创建REACT代理图
# 这个图将管理代理的推理和执行流程
graph = create_react_agent(llm, tools=tools)


# 定义一个函数用于打印流式输出的数据
def print_stream(stream):
    """
    流式打印代理的响应消息

    Args:
        stream: 代理返回的流式响应数据
    """
    for s in stream:
        # 获取最新的消息
        message = s["messages"][-1]
        if isinstance(message, tuple):
            # 如果是元组格式的消息，直接打印
            print(message)
        else:
            # 使用pretty_print方法美化打印消息
            message.pretty_print()


# 尝试一个不需要工具的问题，测试基础功能
print("=== 测试基础问题（不需要工具）===")
inputs = {"messages": [("user", "谁创建了你？")]}
print_stream(graph.stream(inputs, stream_mode="values"))

# 可以添加更多测试用例
print("\n=== 测试天气查询功能 ===")
# 测试需要使用工具的问题
weather_inputs = {"messages": [("user", "纽约的天气怎么样？")]}
print_stream(graph.stream(weather_inputs, stream_mode="values"))
